#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
__docformat__ = "restructuredtext en"

from .. import pilelib as stack
from ..utillib.misc import kwdefault
from .. import comparecards as cmp_cards
from ..packlib import info as cs


class TrumpFoundation(stack.SS_Foundation):

    def cardsBuild(self, from_stack, cards):
        if not super(TrumpFoundation, self).cardsBuild(from_stack, cards):
            return False
        return all(s.is_filled for s in self.game.s['foundations'][:4])


class CmpPile_Method(object):

    _range = (0, 0)

    def _sequence(self, cards):
        """
        _sequence(cards) -> bool

        :Parameters:
          cards: tuple
            Row's foundation card and cards from sending pile

        :returns: accept card sequence?
        """
        return True

    def cardsBuild(self, from_stack, cards):
        """
        _cardsBuild(from_stack, cards) -> bool

        Build cards checking parent then any suit but trump provided card
        right have cards and is in _sequence with row's foundation base card.

        :Parameters:
          from_stack: Stack
            Sending pile

          cards: tuple
            cards from sending pile

        :returns: accept card sequence?
        """
        if (not super(CmpPile_Method, self).cardsBuild(from_stack, cards) or
            cards[0]['suit'] == cs.TRUMP):
            return False
        s = self.game.s
        col = int((self._range[1] + 1) / 4)
        row = int(self.id / col)
        start = self._range[0] + row * col
        # Cards from right to left before are not empty in row
        if any(not r.cards for r in s['rows'][start: self.id]):
            return False
        return self._sequence(s['foundations'][row].cards[-1:] + cards)


class Bits_RowStack(CmpPile_Method, stack.ReserveStack):

    _range = (0, 15)

    def _sequence(self, cards):
        """
        _sequence(cards) -> bool

        Cards rank shifts right by col position as bit.

        :Parameters:
          cards: tuple
            Row's foundation card and cards from sending pile

        :returns: accept card sequence?
        """
        return cmp_cards.isRankBitShiftSequence(cards, dir=int(self.id % 4))


class Bytes_RowStack(CmpPile_Method, stack.ReserveStack):

    _range = (16, 23)

    def _sequence(self, cards):
        """
        _sequence(cards) -> bool

        Cards are same rank.

        :Parameters:
          cards: tuple
            Row's foundation card and cards from sending pile

        :returns: accept card sequence?
        """
        return cmp_cards.isSameRank(cards)


class TW_AC_RowStack(stack.AC_RowStack):

    def _sequence(self, cards):
        """
        _sequence(cards) -> bool

        Cards are parent sequence except trump play wild.

        :Parameters:
          cards: tuple
            Top card and cards from sending pile

        :returns: accept card sequence?
        """
        if cs.TRUMP in cards[:2]:
            return True
        return super(TW_AC_RowStack, self)._sequence(cards)


class TR_AC_RowStack(stack.AC_RowStack):

    def _sequence(self, cards):
        """
        _sequence(cards) -> bool

        Cards are parent sequence except trump play rank order.

        :Parameters:
          cards: tuple
            Top card and cards from sending pile

        :returns: accept card sequence?
        """
        if cs.TRUMP in cards[:2]:
            return cmp_cards.isRankSequence(cards[:2], **self.cap)
        return super(TR_AC_RowStack, self)._sequence(cards)


class TrumpReserve(stack.ReserveStack):
    _BOTTOM_IMAGE_ = 'suit'

    def __init__(self, x, y, game, **cap):
        kwdefault(cap, suit=cs.TRUMP, base_suit=cs.TRUMP, max_cards=3)
        super(TrumpReserve, self).__init__(x, y, game, **cap)